/*
 * Copyright (c) 2011 Ondrej Lapacek
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you
 * may not use this file except in compliance with the License. You may
 * obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */

/**
 * @author      Ondrej Lapacek
 * @version     1.0, 09/12/11
 * @since       1.0
 */

package cz.muni.fi.android.assistivecamera.location;

import android.app.Service;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import cz.muni.fi.android.assistivecamera.AssistiveCameraActivity;
import cz.muni.fi.android.assistivecamera.R;


public class GPSReader extends Service implements LocationListener {

	private boolean gpsInit = false;
	private AssistiveCameraActivity gpsReciever = null;
	private LocationManager locManager = null;
	private long defaultMinTime = 1000L;
	private float defaultMinDistance = 1.0f;
	
	private String provider;
	
	
	private static final String TAG = "GPS Reader";	

	public void startGPS() {
		startGPS(-1L, 1.0f);
	}
	public void startGPS(long minTime, float minDistance) {
		if (minTime == -1L) {
			minTime = defaultMinTime;
		}
		if (minDistance == -1.0f) {
			minDistance = defaultMinDistance;
		}
		if(locManager.isProviderEnabled(LocationManager.GPS_PROVIDER))
		{
			this.provider = LocationManager.GPS_PROVIDER;
			locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, minTime, minDistance, this);
			gpsInit = locManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
			if(gpsReciever!=null){
				gpsReciever.updateLocation(locManager.getLastKnownLocation(LocationManager.GPS_PROVIDER), getResources().getString(R.string.fixed));
			}
		}
		else
		{
			locManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, minTime, minDistance, this);
			gpsInit = locManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
			this.provider = LocationManager.NETWORK_PROVIDER;
			Log.d("Warning", "Using Network instead of GPS.");
			if(gpsReciever!=null){
				gpsReciever.updateLocation(locManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER), getResources().getString(R.string.fixed));
			}
		}
		
	}
    
	public void stopGPS() {
    	locManager.removeUpdates(this);
    	locManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, defaultMinTime, defaultMinDistance, this);
    	gpsInit = locManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
	}

	// Startup code
    /**
     * Class for clients to access.  Because we know this service always
     * runs in the same process as its clients, we don't need to deal with
     * IPC.
     */
    public class LocalBinder extends Binder {
        public GPSReader getService(AssistiveCameraActivity currentGPSReciever) {
        	gpsReciever = currentGPSReciever;
        	if (gpsInit) {
        		Log.d(TAG, "gpsReciever.setGPSEnabled();");
    			gpsReciever.setGPSEnabled();
    		} else {
    			Log.d(TAG, "gpsReciever.setGPSDisabled();");
    			gpsReciever.setGPSDisabled();
    		
    		}
    		
            return GPSReader.this;
        }
    }
    
    @Override
	public void onCreate() {
		locManager = (LocationManager) getSystemService(LOCATION_SERVICE);
		startGPS();
	}
    
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
    	startGPS();
    	return super.onStartCommand(intent, flags, startId);
   	}
    
    @Override
    public void onDestroy() {
    	stopGPS();
    	gpsReciever = null;
    }
    
    // Object that receives interactions from clients
    private final IBinder mBinder = new LocalBinder();
    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    // Status update
    public void onProviderEnabled(String provider) {
    	if (provider.equals(LocationManager.GPS_PROVIDER)) {
    		gpsInit = true;
    		if (gpsReciever != null) {
    			gpsReciever.setGPSEnabled();
			}
    	}
    }
 
    public void onProviderDisabled(String provider) {
    	if (provider.equals(LocationManager.GPS_PROVIDER)) {
    		gpsInit = false;
    		if (gpsReciever != null) {
    			gpsReciever.setGPSDisabled();
			}
    	}
    }
   
	public void onLocationChanged(Location location) {
    	if (gpsReciever != null) {
		 	gpsReciever.updateLocation(location, getResources().getString(R.string.fixed));
    	}
    }
    
	public void onStatusChanged(String provider, int status, Bundle extras) {
    	if (provider.equals(LocationManager.GPS_PROVIDER)) {
    		switch (status) {
    		case LocationProvider.AVAILABLE:
    			if (gpsReciever != null) {
    				gpsReciever.setStatus(0);
    			}
    			break;
    		case LocationProvider.TEMPORARILY_UNAVAILABLE:
    			if (gpsReciever != null) {
    				gpsReciever.setStatus(1);
    			}
    			break;
    		case LocationProvider.OUT_OF_SERVICE:
    			if (gpsReciever != null) {
    				gpsReciever.setStatus(2);
    			}
    			break;
    		}
    	}
	}
	
	public String getProvider()
	{
		return provider;
	}
	
}
